# -*- coding: utf-8 -*-

import random
import string

from math import floor, ceil
from copy import deepcopy

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.axes import Axes

from mpl_matplotlib import mpl_font
from mpl_Axes import remove_border


def mpl_plot():
    """折线图"""
    ax: Axes = plt.subplot()
    ax.set_title(label="折线图")
    data_len = 10  # 数据记录数量
    show_num = 8  # 刻度显示数量

    x = np.linspace(start=1, stop=data_len, num=data_len)
    y = np.random.random(size=data_len)

    tick = ax.tick_params(axis='x', labelrotation=45)
    ax.set_xlabel(xlabel='X轴')

    x_step = floor(len(x) / show_num)
    x_step = 1 if x_step == 0 else x_step  # 解决data_len < show_num报错
    x_tick = list(range(0, len(x), x_step))
    x_tick[-1] = len(x) - 1
    ax.xaxis.set_ticks(ticks=x_tick)
    x_tick_label = deepcopy(x)[::x_step]  # 深度复制
    x_tick_label[-1] = x[-1]  # 显示最后一个数据
    f = np.frompyfunc(lambda i: f'第{int(i)}个点', 1, 1)
    x_tick_label = f(x_tick_label)
    ax.xaxis.set_ticklabels(ticklabels=x_tick_label)

    y_unit = 0.01
    item_max = ceil(max(y) / y_unit)
    item_min = floor(min(y) / y_unit)

    y_step = floor((item_max - item_min + 1) / show_num)
    y_step = 1 if y_step == 0 else y_step  # 解决数据范围太小问题
    y_item = list(range(item_min - y_step * 2, item_max + 1 + y_step * 2, y_step))
    y_tick = [i * y_unit for i in y_item]
    ax.yaxis.set_ticks(ticks=y_tick)
    ax.set_ylim(bottom=(min(y_item) - y_step * 1) * y_unit, top=(max(y_item) + y_step * 2) * y_unit)

    # 折线图
    line = ax.plot(x, y, label='图例', color='#356FAC')
    # 填充颜色
    ax.fill_between(x=x, y1=(item_min - y_step) * y_unit, y2=y, facecolor='cyan', alpha=0.3)
    # 面积图
    # ax.stackplot(x, y, labels=['图例'], colors=['cyan'], alpha=0.3)
    ax.grid(axis='y', color='gray')
    ax.legend(loc='upper center', fontsize='xx-large', frameon=False)
    pass


def mpl_bar():
    """柱状图"""
    ax: Axes = plt.subplot()
    ax.set_title(label="柱状图")
    data_max = 5
    data_min = 2
    data_num = 5
    x1 = list(string.ascii_uppercase[:data_num])
    x2 = np.arange(data_num)
    y1, y2 = np.random.randint(data_min, data_max, size=(2, data_num))
    width = 0.25

    # grouped
    # ax.bar(x=x2 - width / 2, height=y1, width=width, label='y1')
    # ax.bar(x=x2 + width / 2, height=y2, width=width, label='y2')
    # ax.set_ylim(bottom=data_min, top=data_max)

    # stacked
    # ax.bar(x=x2, height=y1, width=width, label='y1')
    # ax.bar(x=x2, height=y2, width=width, label='y2', bottom=y1)
    # ax.set_ylim(bottom=data_min, top=max(y1 + y2) * 1.1)

    # ax.xaxis.set_ticks(ticks=x2)
    # ax.xaxis.set_ticklabels(ticklabels=x1)

    # h
    ax.barh(y=x2 - width / 2, width=y1, height=width, label='y1')
    # ax.bar(x=x2 + width / 2, height=y2, width=width, label='y2')
    ax.set_xlim(left=data_min, right=data_max)
    ax.yaxis.set_ticks(ticks=x2)
    ax.yaxis.set_ticklabels(ticklabels=x1)
    ax.invert_yaxis()

    ax.legend()

    pass


def mpl_pie():
    """饼图"""
    ax: Axes = plt.subplot()
    ax.set_title(label="饼图")

    x = [0.001, 0.01, 0.289, 0.3, 0.4]
    label = [f'这是第{i}部分' for i in list(string.ascii_lowercase[:len(x)])]
    pie = ax.pie(x=x, labels=label, autopct='%.2f%%')
    # bbox_to_anchor=(x, y, width, height)
    legend = ax.legend(label, loc='upper left', bbox_to_anchor=(1, 0, 0.5, 1))

    pass


def mpl_hist():
    """直方图"""
    plt.title(label="直方图")

    plt.hist(np.random.randn(100), bins=10, color='b', alpha=0.3)
    pass


def mpl_scatter():
    """散点图"""
    plt.title(label="散点图")

    x = np.arange(50)
    y = x + 5 * np.random.rand(50)
    plt.scatter(x, y)
    pass


def mpl_imshow():
    """热图"""
    m = np.random.rand(10, 10)
    plt.imshow(m, interpolation='nearest', cmap=plt.cm.ocean)
    plt.colorbar()
    pass


if __name__ == '__main__':
    mpl_font()

    mpl_plot()
    # mpl_bar()
    # mpl_pie()

    # mpl_hist()
    # mpl_scatter()
    # mpl_imshow()

    plt.show()
    pass
